<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Fault Tolerance</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/microprofile-fault-tolerance" />
  <meta property="og:title" content="Quarkus - Fault Tolerance" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/microprofile-fault-tolerance">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Fault Tolerance</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#the-scenario">The Scenario</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#creating-the-maven-project">Creating the Maven Project</a></li>
<li><a href="#preparing-an-application-rest-endpoint-and-cdi-bean">Preparing an Application: REST Endpoint and CDI Bean</a></li>
<li><a href="#adding-resiliency-retries">Adding Resiliency: Retries</a></li>
<li><a href="#adding-resiliency-timeouts">Adding Resiliency: Timeouts</a></li>
<li><a href="#adding-resiliency-fallbacks">Adding Resiliency: Fallbacks</a></li>
<li><a href="#adding-resiliency-circuit-breaker">Adding Resiliency: Circuit Breaker</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>One of the challenges brought by the distributed nature of microservices is that communication with external systems is
inherently unreliable. This increases demand on resiliency of applications. To simplify making more resilient
applications, Quarkus contains an implementation of the MicroProfile Fault Tolerance specification.</p>
</div>
<div class="paragraph">
<p>In this guide, we demonstrate usage of MicroProfile Fault Tolerance annotations such as <code>@Timeout</code>, <code>@Fallback</code>,
<code>@Retry</code> and <code>@CircuitBreaker</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="the-scenario"><a class="anchor" href="#the-scenario"></a>The Scenario</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The application built in this guide simulates a simple backend for a gourmet coffee e-shop. It implements a REST
endpoint providing information about coffee samples we have on store.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s imagine, although it&#8217;s not implemented as such, that some of the methods in our endpoint require communication
to external services like a database or an external microservice, which introduces a factor of unreliability.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>microprofile-fault-tolerance-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/microprofile-fault-tolerance-quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-maven-project"><a class="anchor" href="#creating-the-maven-project"></a>Creating the Maven Project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First, we need a new project. Create a new project with the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=microprofile-fault-tolerance-quickstart \
    -DclassName="org.acme.microprofile.faulttolerance.CoffeeResource" \
    -Dpath="/coffee" \
    -Dextensions="smallrye-fault-tolerance, resteasy-jsonb"
cd microprofile-fault-tolerance-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command generates a Maven structure, importing the extensions for RESTEasy/JAX-RS
and SmallRye Fault Tolerance, which is an implementation of the MicroProfile Fault Tolerance spec that Quarkus uses.</p>
</div>
<div class="paragraph">
<p>If you already have your Quarkus project configured, you can add the <code>smallrye-fault-tolerance</code> extension
to your project by running the following command in your project base directory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./mvnw quarkus:add-extension -Dextensions="smallrye-fault-tolerance"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will add the following to your <code>pom.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-smallrye-fault-tolerance&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="preparing-an-application-rest-endpoint-and-cdi-bean"><a class="anchor" href="#preparing-an-application-rest-endpoint-and-cdi-bean"></a>Preparing an Application: REST Endpoint and CDI Bean</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this section we create a skeleton of our application, so that we have something that we can extend and to which
we can add fault tolerance features later on.</p>
</div>
<div class="paragraph">
<p>First, create a simple entity representing a coffee sample in our store:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.microprofile.faulttolerance;

public class Coffee {

    public Integer id;
    public String name;
    public String countryOfOrigin;
    public Integer price;

    public Coffee() {
    }

    public Coffee(Integer id, String name, String countryOfOrigin, Integer price) {
        this.id = id;
        this.name = name;
        this.countryOfOrigin = countryOfOrigin;
        this.price = price;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Let&#8217;s continue with a simple CDI bean, that would work as a repository of our coffee samples.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.microprofile.faulttolerance;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class CoffeeRepositoryService {

    private Map&lt;Integer, Coffee&gt; coffeeList = new HashMap&lt;&gt;();

    public CoffeeRepositoryService() {
        coffeeList.put(1, new Coffee(1, "Fernandez Espresso", "Colombia", 23));
        coffeeList.put(2, new Coffee(2, "La Scala Whole Beans", "Bolivia", 18));
        coffeeList.put(3, new Coffee(3, "Dak Lak Filter", "Vietnam", 25));
    }

    public List&lt;Coffee&gt; getAllCoffees() {
        return new ArrayList&lt;&gt;(coffeeList.values());
    }

    public Coffee getCoffeeById(Integer id) {
        return coffeeList.get(id);
    }

    public List&lt;Coffee&gt; getRecommendations(Integer id) {
        if (id == null) {
            return Collections.emptyList();
        }
        return coffeeList.values().stream()
                .filter(coffee -&gt; !id.equals(coffee.id))
                .limit(2)
                .collect(Collectors.toList());
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Finally, edit the <code>org.acme.microprofile.faulttolerance.CoffeeResource</code> class as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.microprofile.faulttolerance;

import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.jboss.logging.Logger;

@Path("/coffee")
@Produces(MediaType.APPLICATION_JSON)
public class CoffeeResource {

    private static final Logger LOGGER = Logger.getLogger(CoffeeResource.class);

    @Inject
    private CoffeeRepositoryService coffeeRepository;

    private AtomicLong counter = new AtomicLong(0);

    @GET
    public List&lt;Coffee&gt; coffees() {
        final Long invocationNumber = counter.getAndIncrement();

        maybeFail(String.format("CoffeeResource#coffees() invocation #%d failed", invocationNumber));

        LOGGER.infof("CoffeeResource#coffees() invocation #%d returning successfully", invocationNumber);
        return coffeeRepository.getAllCoffees();
    }

    private void maybeFail(String failureLogMessage) {
        if (new Random().nextBoolean()) {
            LOGGER.error(failureLogMessage);
            throw new RuntimeException("Resource failure.");
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>At this point, we expose a single REST method that will show a list of coffee samples in a JSON format. Note
that we introduced some fault making code in our <code>CoffeeResource#maybeFail()</code> method, which is going to cause failures
in the <code>CoffeeResource#coffees()</code> endpoint method in about 50 % of requests.</p>
</div>
<div class="paragraph">
<p>Why not check that our application works? Run the Quarkus development server with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw compile quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>and open <code><a href="http://localhost:8080/coffee" class="bare">http://localhost:8080/coffee</a></code> in your browser. Make couple of requests (remember, some of them we expect
to fail). At least some of the requests should show us the list of our coffee samples in JSON, the rest will fail
with a <code>RuntimeException</code> thrown in <code>CoffeeResource#maybeFail()</code>.</p>
</div>
<div class="paragraph">
<p>Congratulations, you&#8217;ve just made a working (although somewhat unreliable) Quarkus application!</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="adding-resiliency-retries"><a class="anchor" href="#adding-resiliency-retries"></a>Adding Resiliency: Retries</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let the Quarkus development server running and in your IDE add the <code>@Retry</code> annotation to the <code>CoffeeResource#coffees()</code>
method as follows and save the file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import org.eclipse.microprofile.faulttolerance.Retry;
...

public class CoffeeResource {
    ...
    @GET
    @Retry(maxRetries = 4)
    public List&lt;Coffee&gt; coffees() {
        ...
    }
    ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Hit refresh in your browser. The Quarkus development server will automatically detect the changes
and recompile the app for you, so there&#8217;s no need to restart it.</p>
</div>
<div class="paragraph">
<p>You can hit refresh couple more times. Practically all requests should now be succeeding. The <code>CoffeeResource#coffees()</code>
method is still in fact failing in about 50 % of time, but every time it happens, the platform will automatically retry
the call!</p>
</div>
<div class="paragraph">
<p>To see that that the failures still happen, check the output of the development server. The log messages should be
similar to these:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">2019-03-06 12:17:41,725 INFO  [org.acm.fau.CoffeeResource] (XNIO-1 task-1) CoffeeResource#coffees() invocation #5 returning successfully
2019-03-06 12:17:44,187 INFO  [org.acm.fau.CoffeeResource] (XNIO-1 task-1) CoffeeResource#coffees() invocation #6 returning successfully
2019-03-06 12:17:45,166 ERROR [org.acm.fau.CoffeeResource] (XNIO-1 task-1) CoffeeResource#coffees() invocation #7 failed
2019-03-06 12:17:45,172 ERROR [org.acm.fau.CoffeeResource] (XNIO-1 task-1) CoffeeResource#coffees() invocation #8 failed
2019-03-06 12:17:45,176 INFO  [org.acm.fau.CoffeeResource] (XNIO-1 task-1) CoffeeResource#coffees() invocation #9 returning successfully</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can see that every time an invocation fails, it&#8217;s immediately followed by another invocation, until one succeeds.
Since we allowed 4 retries, it would require 5 invocations to fail in a row, in order for the user to be actually exposed
to a failure. Which is fairly unlikely to happen.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="adding-resiliency-timeouts"><a class="anchor" href="#adding-resiliency-timeouts"></a>Adding Resiliency: Timeouts</h2>
<div class="sectionbody">
<div class="paragraph">
<p>So what else have we got in MicroProfile Fault Tolerance? Let&#8217;s look into timeouts.</p>
</div>
<div class="paragraph">
<p>Add following two methods to our <code>CoffeeResource</code> endpoint. Again, no need to restart the server, just paste the code
and save the file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import org.jboss.resteasy.annotations.jaxrs.PathParam;
import org.eclipse.microprofile.faulttolerance.Timeout;
...
public class CoffeeResource {
    ...
    @GET
    @Path("/{id}/recommendations")
    @Timeout(250)
    public List&lt;Coffee&gt; recommendations(@PathParam int id) {
        long started = System.currentTimeMillis();
        final long invocationNumber = counter.getAndIncrement();

        try {
            randomDelay();
            LOGGER.infof("CoffeeResource#recommendations() invocation #%d returning successfully", invocationNumber);
            return coffeeRepository.getRecommendations(id);
        } catch (InterruptedException e) {
            LOGGER.errorf("CoffeeResource#recommendations() invocation #%d timed out after %d ms",
                    invocationNumber, System.currentTimeMillis() - started);
            return null;
        }
    }

    private void randomDelay() throws InterruptedException {
        Thread.sleep(new Random().nextInt(500));
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>We added some new functionality. We want to be able to recommend some related coffees based on a coffee that a user
is currently looking at. It&#8217;s not a critical functionality, it&#8217;s a nice-to-have. When the system is overloaded and the
logic behind obtaining recommendations takes too long to execute, we would rather time out and render the UI without
recommendations.</p>
</div>
<div class="paragraph">
<p>Note that the timeout was configured to 250 ms, and a random artificial delay between 0 to 500 ms was introduced
into the <code>CoffeeResource#recommendations()</code> method.</p>
</div>
<div class="paragraph">
<p>In your browser, go to <code><a href="http://localhost:8080/coffee/2/recommendations" class="bare">http://localhost:8080/coffee/2/recommendations</a></code> and hit refresh a couple of times.</p>
</div>
<div class="paragraph">
<p>You should see some requests time out with <code>org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException</code>.
Requests that do not time out should show two recommended coffee samples in JSON.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="adding-resiliency-fallbacks"><a class="anchor" href="#adding-resiliency-fallbacks"></a>Adding Resiliency: Fallbacks</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let&#8217;s make our recommendations feature even better by providing a fallback (and presumably faster) way of getting related
coffees.</p>
</div>
<div class="paragraph">
<p>Add a fallback method to <code>CoffeeResource</code> and a <code>@Fallback</code> annotation to <code>CoffeeResource#recommendations()</code> method
as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import java.util.Collections;
import org.eclipse.microprofile.faulttolerance.Fallback;
...
public class CoffeeResource {
    ...
    @Fallback(fallbackMethod = "fallbackRecommendations")
    public List&lt;Coffee&gt; recommendations(@PathParam int id) {
        ...
    }

    public List&lt;Coffee&gt; fallbackRecommendations(int id) {
        LOGGER.info("Falling back to RecommendationResource#fallbackRecommendations()");
        // safe bet, return something that everybody likes
        return Collections.singletonList(coffeeRepository.getCoffeeById(1));
    }
    ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Hit refresh several times on <code><a href="http://localhost:8080/coffee/2/recommendations" class="bare">http://localhost:8080/coffee/2/recommendations</a></code>.
The <code>TimeoutException</code> should not appear anymore. Instead, in case of a timeout, the page will
display a single recommendation that we hardcoded in our fallback method <code>fallbackRecommendations()</code>, rather than
two recommendations returned by the original method.</p>
</div>
<div class="paragraph">
<p>Check the server output to see that fallback is really happening:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">2020-01-09 13:21:34,250 INFO  [org.acm.fau.CoffeeResource] (executor-thread-1) CoffeeResource#recommendations() invocation #1 returning successfully
2020-01-09 13:21:36,354 ERROR [org.acm.fau.CoffeeResource] (executor-thread-1) CoffeeResource#recommendations() invocation #2 timed out after 250 ms
2020-01-09 13:21:36,355 INFO  [org.acm.fau.CoffeeResource] (executor-thread-1) Falling back to RecommendationResource#fallbackRecommendations()</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The fallback method is required to have the same parameters as the original method.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="adding-resiliency-circuit-breaker"><a class="anchor" href="#adding-resiliency-circuit-breaker"></a>Adding Resiliency: Circuit Breaker</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A circuit breaker is useful for limiting number of failures happening in the system, when part of the system becomes
temporarily unstable. The circuit breaker records successful and failed invocations of a method, and when the ratio
of failed invocations reaches the specified threshold, the circuit breaker <em>opens</em> and blocks all further invocations
of that method for a given time.</p>
</div>
<div class="paragraph">
<p>Add the following code into the <code>CoffeeRepositoryService</code> bean, so that we can demonstrate a circuit breaker in action:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
...

public class CoffeeRepositoryService {
    ...

    private AtomicLong counter = new AtomicLong(0);

    @CircuitBreaker(requestVolumeThreshold = 4)
    public Integer getAvailability(Coffee coffee) {
        maybeFail();
        return new Random().nextInt(30);
    }

    private void maybeFail() {
        // introduce some artificial failures
        final Long invocationNumber = counter.getAndIncrement();
        if (invocationNumber % 4 &gt; 1) { // alternate 2 successful and 2 failing invocations
            throw new RuntimeException("Service failed.");
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>And inject the code below into the <code>CoffeeResource</code> endpoint:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class CoffeeResource {
    ...
    @Path("/{id}/availability")
    @GET
    public Response availability(@PathParam int id) {
        final Long invocationNumber = counter.getAndIncrement();

        Coffee coffee = coffeeRepository.getCoffeeById(id);
        // check that coffee with given id exists, return 404 if not
        if (coffee == null) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        try {
            Integer availability = coffeeRepository.getAvailability(coffee);
            LOGGER.infof("CoffeeResource#availability() invocation #%d returning successfully", invocationNumber);
            return Response.ok(availability).build();
        } catch (RuntimeException e) {
            String message = e.getClass().getSimpleName() + ": " + e.getMessage();
            LOGGER.errorf("CoffeeResource#availability() invocation #%d failed: %s", invocationNumber, message);
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                    .entity(message)
                    .type(MediaType.TEXT_PLAIN_TYPE)
                    .build();
        }
    }
    ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>We added another functionality - the application can return the amount of remaining packages of given coffee on our store
(just a random number).</p>
</div>
<div class="paragraph">
<p>This time an artificial failure was introduced in the CDI bean: the <code>CoffeeRepositoryService#getAvailability()</code> method is
going to alternate between two successful and two failed invocations.</p>
</div>
<div class="paragraph">
<p>We also added a <code>@CircuitBreaker</code> annotation with <code>requestVolumeThreshold = 4</code>. <code>CircuitBreaker.failureRatio</code> is
by default 0.5, and <code>CircuitBreaker.delay</code> is by default 5 seconds. That means that a circuit breaker will open
when 2 of the last 4 invocations failed and it will stay open for 5 seconds.</p>
</div>
<div class="paragraph">
<p>To test this out, do the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Go to <code><a href="http://localhost:8080/coffee/2/availability" class="bare">http://localhost:8080/coffee/2/availability</a></code> in your browser. You should see a number being returned.</p>
</li>
<li>
<p>Hit refresh, this second request should again be successful and return a number.</p>
</li>
<li>
<p>Refresh two more times. Both times you should see text "RuntimeException: Service failed.", which is the exception
thrown by <code>CoffeeRepositoryService#getAvailability()</code>.</p>
</li>
<li>
<p>Refresh a couple more times. Unless you waited too long, you should again see exception, but this time it&#8217;s
"CircuitBreakerOpenException: getAvailability". This exception indicates that the circuit breaker opened
and the <code>CoffeeRepositoryService#getAvailability()</code> method is not being called anymore.</p>
</li>
<li>
<p>Give it 5 seconds during which circuit breaker should close and you should be able to make two successful requests
again.</p>
</li>
</ol>
</div>
</div>
</div>
<div class="sect1">
<h2 id="conclusion"><a class="anchor" href="#conclusion"></a>Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>MicroProfile Fault Tolerance allows to improve resiliency of your application, without having an impact on the complexity
of our business logic.</p>
</div>
<div class="paragraph">
<p>All that is needed to enable the fault tolerance features in Quarkus is:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>adding the <code>smallrye-fault-tolerance</code> Quarkus extension to your project using the <code>quarkus-maven-plugin</code>:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw quarkus:add-extension -Dextensions="smallrye-fault-tolerance"</code></pre>
</div>
</div>
</li>
<li>
<p>or simply adding the following Maven dependency:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-smallrye-fault-tolerance&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
